/**
 * IScroll5List使用说明：
 *      param.wrap iscrollwrap（外层的div，视域）
 *      param.onLoadData 上拉请求更多数据回调
 *      param.bindEvent 绑定事件(函数)
 *      param.usePullUp 是否允许上拉加载更多，默认true，如果设置为false，则上拉加载更多滑块自动隐藏
 *      param.usePullDown 是否允许下拉刷新，默认true，如果设置为false，则下拉刷新滑块自动隐藏
 *      param.hidePullUp 是否隐藏上拉加载更多滑块，默认false，滑块是否隐藏不影响功能是否被调用
 *      param.hidePullDown 是否隐藏下拉刷新滑块，默认false，滑块是否隐藏不影响功能是否被调用
 *
 * 控件不提供针对数据逻辑的处理，以下逻辑需要在调用端自行判断，比如
 *      禁用下拉刷新，调用disablePullDown()方法
 *      启用下拉刷新，调用enablePullDown()方法
 *      无更多数据时禁用上拉，调用disablePullUp()方法
 *      启用上拉刷新，调用enablePullUp()方法
 *      无数据时展示暂无数据页面，调用showNoData()方法，此时支持下拉刷新
 * 控件不提供请求数据时的waiting，如果需要，请使用$.Waiting();
 *
 * @dependency jquery
 * @author Keith
 */
/*global define navigator document :true*/
define([
    "jquery", "iscroll-probe"
], function($, IScroll) {
    function IScroll5List(param) {
        this.params = $.extend({
            wrap: null,
            bindEvent: null,
            onRefresh: null,
            onLoadData: null,
            usePullUp: true,
            usePullDown: true,
            hidePullUp: false,
            hidePullDown: false
        }, param);
        if(!this.params.usePullDown) {
            this.params.hidePullDown = true;
        }
        if(!this.params.usePullUp) {
            this.params.hidePullUp = true;
        }

        this.statusFlag = 0; // 0:静态初始状态 1:正在加载中 2:加载完成状态
        this.dataOffset = 0;
        this.myScroll;
        this.$container;
        this.$scroller;
        this.$content;
        this.$pullDownEl;
        this.$pullUpEl;

        this.pullUpElStyle = this.params.hidePullUp? "pullUp_hide" : "pullUp";
        this.pullDownElStyle = this.params.hidePullDown? "pullDown_hide" : "pullDown";

        this.pullDownText = "下拉刷新...";
        this.pullUpText = "上拉加载更多...";
        this.refreshText = "释放刷新...";
        this.loadingText = "正在加载...";

        if (!this.params.wrap) {
            return;
        }

        this._initUI();
        this._initIscroll();
    }

    IScroll5List.prototype._initUI = function() {
        var _this = this;

        _this.$scroller = $("<div class='scroller'></div>");
        _this.$container = $("#" + _this.params.wrap);
        _this.$container.append(_this.$scroller);

        _this.$pullDownEl = $("<div class='" + this.pullDownElStyle + "'><span class='pullDownIcon'></span><span class='pullDownLabel'>" + this.pullDownText + "</span></div>");
        _this.$pullUpEl = $("<div class='" + this.pullUpElStyle + "'><span class='pullUpIcon'></span><span class='pullUpLabel'>" + this.pullUpText + "</span></div>");
        _this.$content = $("<div class='scroller-content'></div>");
        _this.$scroller.append(_this.$pullDownEl).append(_this.$content).append(_this.$pullUpEl);

        if (_this.$container.height() > _this.$content.height()) {
            _this.$content.css({
                // 至少要保证scroller比wrapper大1，否则将不会滚动
                "min-height": (_this.$container.height() - _this.$pullDownEl.height() + 1) + "px"
            });
        }
    };

    IScroll5List.prototype._initIscroll = function() {
        var _this = this;

        var pullDownOffset = 0;
        var pullDownEl = _this.$pullDownEl.get(0);
        if (pullDownEl) {
            pullDownOffset = pullDownEl.offsetHeight;
        } else {
            pullDownOffset = 0;
        }
        var pullUpEl = _this.$pullUpEl.get(0);
        _this.myScroll = _this.touchScroll("#" + _this.params.wrap, {
            mouseWheel: false, // 是否监听鼠标滚轮事件。
            scrollbars: false, // 是否显示默认滚动条
            fadeScrollbars: false, // 是否渐隐滚动条，关掉可以加速
            probeType: 1
        });

        _this.myScroll.on("refresh", function() {
            if (pullDownEl.className.match('loading')) {
                pullDownEl.className = _this.pullDownElStyle;
                pullDownEl.querySelector('.pullDownLabel').innerHTML = _this.pullDownText;
            } else if (pullUpEl.className.match('loading')) {
                pullUpEl.className = _this.pullUpElStyle;
                pullUpEl.querySelector('.pullUpLabel').innerHTML = _this.pullUpText;
            }
            _this.myScroll.enable();
            _this.dealOffset();
        });
        _this.myScroll.on("scroll", function() {
            if (this.y > 5 && pullDownEl && !pullDownEl.className.match('flip')) {
                pullDownEl.className = _this.pullDownElStyle + ' flip';
                pullDownEl.querySelector('.pullDownLabel').innerHTML = _this.refreshText;
                this.minScrollY = 0;
            } else if (this.y < 5 && pullDownEl && pullDownEl.className.match('flip')) {
                pullDownEl.className = _this.pullDownElStyle;
                pullDownEl.querySelector('.pullDownLabel').innerHTML = _this.pullDownText;
                this.minScrollY = -pullDownOffset;
            } else if (this.y < (this.maxScrollY - 5) && !pullUpEl.className.match('flip')) {
                pullUpEl.className = _this.pullUpElStyle + ' flip';
                pullUpEl.querySelector('.pullUpLabel').innerHTML = _this.refreshText;
                this.maxScrollY = this.maxScrollY;
            } else if (this.y > (this.maxScrollY - 5) && pullUpEl.className.match('flip')) {
                pullUpEl.className = _this.pullUpElStyle;
                pullUpEl.querySelector('.pullUpLabel').innerHTML = _this.pullUpText;
            }
            _this.$content.trigger("scroll");
        });
        _this.myScroll.on("scrollEnd", function() {
            if (pullDownEl.className.match('flip')) {
                pullDownEl.className = 'loading';
                pullDownEl.querySelector('.pullDownLabel').innerHTML = _this.loadingText;
                if(_this.params.usePullDown) {
                    _this._pullDownAction();
                } else {
                    this.refresh();
                }
            } else if (pullUpEl.className.match('flip') && pullUpEl.className.indexOf("loading") < 0) {
                pullUpEl.className = 'loading';
                pullUpEl.querySelector('.pullUpLabel').innerHTML = _this.loadingText;
                if (_this.params.usePullUp) {
                    _this._pullUpAction();
                } else {
                    this.refresh();
                }
            } else {
                _this.dealOffset();
            }
        });
        setTimeout(function() {
            _this._pullUpAction();
        }, 300);
    };

    /**
     * 处理头部的位移
     * iScroll5中不再支持offset参数，需要自行处理offset
     * @author Keith
     */
    IScroll5List.prototype.dealOffset = function() {
        var _this = this;
        var pullDownOffset = 0;
        var pullDownEl = _this.$pullDownEl.get(0);
        if (pullDownEl) {
            pullDownOffset = pullDownEl.offsetHeight;
        } else {
            pullDownOffset = 0;
        }

        if((_this.$scroller.height() - _this.$pullDownEl.height() - 1 <= _this.$container.height())
            || (Math.abs(_this.myScroll.y) < _this.$pullDownEl.height())) {
            _this.myScroll.scrollTo(0, -pullDownOffset);
        }
    };

    IScroll5List.prototype.touchScroll = function(elem, options) {
        if (typeof(elem) == "object") {
            elem = elem[0];
        }
        // 处理滚动手势
        options = options || {};
        //
        options.startX = options.startX || 0;
        options.startY = options.startY || 0;
        // 惯性
        options.momentum = true; // 允许有惯性滑动
        options.click = true;
        options.probeType = 1;
        options.bounce = true; //边界反弹
        options.shrinkScrollbars = "scale"; // 当滚动边界之外的滚动条是由少量的收缩。'clip' or 'scale'.
        options.mouseWheel = true, // 是否监听鼠标滚轮事件。
        options.scrollbars = false, // 是否显示默认滚动条
        options.fadeScrollbars = true, // 是否渐隐滚动条，关掉可以加速
        options.useTransition = this._isTransition();
        if (/iphone/.test(navigator.userAgent.toLowerCase())) {
            options.useTransition = true;
        }
        return new IScroll(elem, options);
    };

    /**
     * 下拉刷新调用，清空列表数据，并从0开始请求数据
     * @author Keith
     * @return {[type]} [description]
     */
    IScroll5List.prototype.refresh = function() {
        this.resetData();
        this._changeStatus(1);
        if (this.params.onLoadData && typeof this.params.onLoadData == "function") {
            this.params.onLoadData.apply(this, [this.dataOffset]);
        }
    };

    /**
     * 清空列表数据
     * @author Keith
     */
    IScroll5List.prototype.resetData = function() {
        if (this.$content) {
            this.$content.html("");
            this.dataOffset = 0;
        }
    };

    /**
     * 获取data offset
     * @author Keith
     */
    IScroll5List.prototype.getDataOffset = function() {
        return this.dataOffset;
    };

    /**
     * 设置data offset
     * @author Keith
     * @param  {int} dataOffset
     */
    IScroll5List.prototype.setDataOffset = function(dataOffset) {
        this.dataOffset = dataOffset;
    };

    /**
     * 重置data offset
     * @author Keith
     */
    IScroll5List.prototype.resetDataOffset = function() {
        this.dataOffset = 0;
    };

    /**
     * 向列表中添加Dom元素，并调用bindEvent方法
     * @author Keith
     * @param  {Dom} dom dom string
     * @param  {int} size 列表元素总数
     */
    IScroll5List.prototype.appendItem = function(dom, size) {
        this.$content.append(dom);
        this.setDataOffset(size);
        this.appendFinish();

        if (this.params.bindEvent) {
            this.params.bindEvent.call(this);
        }
    };

    /**
     * 刷新列表
     * @author Keith
     */
    IScroll5List.prototype.appendFinish = function() {
        var _this = this;
        // 强制刷新html
        _this.$content.hide().show(0);
        _this._changeStatus(2);
        if (!_this.myScroll.enabled) {
            _this.myScroll.enable();
        }
        _this.myScroll.refresh();
    };

    /**
     * 滚动到最后
     * @author Keith
     * @return {[type]} [description]
     */
    IScroll5List.prototype.scrollToEnd = function() {
        this.myScroll.scrollToElement(this.$content.children().last().get(0), 0);
    };

    /**
     * 上拉加载更多
     * @author Keith
     */
    IScroll5List.prototype._pullUpAction = function() {
        if (this._isLoading()) {
            return;
        }
        this.myScroll.disable();
        this._changeStatus(1);
        if (this.params.onLoadData && typeof this.params.onLoadData == "function") {
            this.params.onLoadData.apply(this, [this.dataOffset]);
        }
    };

    /**
     * 下拉刷新
     * @author Keith
     */
    IScroll5List.prototype._pullDownAction = function() {
        if (this._isLoading()) {
            return;
        }
        this.refresh();
    };

    // 辅助函数begin
    IScroll5List.prototype._isLoading = function() {
        return this.statusFlag == 1;
    };

    IScroll5List.prototype._changeStatus = function(status) {
        this.statusFlag = status;
    };

    IScroll5List.prototype._isTransition = function() {
        var dummyStyle = document.createElement('div').style;
        var vendors = 't,webkitT,MozT,msT,OT'.split(','),
            t,
            i = 0,
            l = vendors.length;
        var temp = null;
        for (; i < l; i++) {
            t = vendors[i] + 'ransform';
            if (t in dummyStyle) {
                temp = vendors[i].substr(0, vendors[i].length - 1);
                break;
            }
        }
        if (temp && temp == "") {
            return false;
        } else {
            return true;
        }
    };

    /**
     * 只展示简单的暂无数据页面，不控制页面控制如pulldown/pullup
     * 用户需要根据自己的需求，在调用showNoData前后，控制列表状态
     * @author Keith
     * @param  {Function} cb [description]
     * @return {[type]}      [description]
     */
    IScroll5List.prototype.showNoData = function(cb) {
        var $noDataView = $("<div>暂无数据</div>");
        $noDataView.css({
            "position": "absolute",
            "top": "0",
            "left": "0",
            "line-height": this.$container.height() + "px",
            "text-align": "center",
            "width": "100%",
            "height": this.$container.height() + "px"
        });
        this.$content.html($noDataView);
        $noDataView.unbind("click").bind("click", function() {
            cb.call(this);
        });
    };

    // 以下滚动控制方法并不会修改滑块是否展示
    IScroll5List.prototype.enablePullUp = function() {
        this.params.usePullUp = true;
        this.myScroll.refresh();
    };

    IScroll5List.prototype.enablePullDown = function() {
        this.params.usePullDown = true;
        this.myScroll.refresh();
        this.dealOffset();
    };

    IScroll5List.prototype.disablePullUp = function() {
        this.params.usePullUp = false;
        this.myScroll.refresh();
    };

    IScroll5List.prototype.disablePullDown = function() {
        this.params.usePullDown = false;
        this.myScroll.refresh();
        this.dealOffset();
    };

    IScroll5List.prototype.hidePullUp = function() {
        this.pullUpElStyle = "pullUp_hide";
        this.$pullUpEl.removeClass("pullUp").addClass("pullUp_hide");
        this.myScroll.refresh();
        this.dealOffset();
    };

    IScroll5List.prototype.hidePullDown = function() {
        this.pullDownElStyle = "pullDown_hide";
        this.$pullDownEl.removeClass("pullDown").addClass("pullDown_hide");
        this.myScroll.refresh();
        this.dealOffset();
    };

    IScroll5List.prototype.showPullUp = function() {
        this.pullUpElStyle = "pullUp";
        this.$pullUpEl.removeClass("pullUp_hide").addClass("pullUp");
        this.myScroll.refresh();
        this.dealOffset();
    };

    IScroll5List.prototype.showPullDown = function() {
        this.pullDownElStyle = "pullDown";
        this.$pullDownEl.removeClass("pullDown_hide").addClass("pullDown");
        this.myScroll.refresh();
        this.dealOffset();
    };

    return IScroll5List;
});
